﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

// Additional Libraries
using System.Security.Cryptography;
using System.Text;
using Microsoft.Phone.Shell;


namespace findMePanorama
{
    public partial class RegisterPage : PhoneApplicationPage
    {
        FindMeFriendServiceReference.FindMeFriendServiceClient serviceClient;
        bool validUsername = false;
        bool validName = false;
        bool validPhoneNumber = false;
        bool validEmail = false;
        bool validPassword = false;
        bool validPassword2 = false;

        ProgressIndicator progress;

        public RegisterPage()
        {

            //<-- Progress bar and clock colors -->
            SystemTray.SetIsVisible(this, true);
            SystemTray.SetOpacity(this, 0.0);
            SystemTray.SetBackgroundColor(this, Colors.Black);
            SystemTray.SetForegroundColor(this, Colors.Green);
            progress = new ProgressIndicator();
            progress.IsIndeterminate = true;
            progress.Text = "Loading";
            SystemTray.SetProgressIndicator(this, progress);

            //<-- End progress bar and clock colors -->


            InitializeComponent();
            serviceClient = new FindMeFriendServiceReference.FindMeFriendServiceClient();
            serviceClient.UsernameAlreadyInDBCompleted += new EventHandler<FindMeFriendServiceReference.UsernameAlreadyInDBCompletedEventArgs>(serviceClient_UsernameAlreadyInDBCompleted);
            serviceClient.EmailAlreadyInDBCompleted += new EventHandler<FindMeFriendServiceReference.EmailAlreadyInDBCompletedEventArgs>(serviceClient_EmailAlreadyInDBCompleted);
            serviceClient.PhoneNumberAlreadyInDBCompleted += new EventHandler<FindMeFriendServiceReference.PhoneNumberAlreadyInDBCompletedEventArgs>(serviceClient_PhoneNumberAlreadyInDBCompleted);
            serviceClient.AddNewUserCompleted += new EventHandler<FindMeFriendServiceReference.AddNewUserCompletedEventArgs>(serviceClient_AddNewUserCompleted);
        }

        void serviceClient_AddNewUserCompleted(object sender, FindMeFriendServiceReference.AddNewUserCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Thank You!!! You may now login to Find.Me");
                NavigationService.Navigate(new Uri("/Login.xaml", UriKind.Relative));
             
            }
            else
            {
             
                MessageBox.Show("Find.Me was unable to register you! Please verify all your information and try again.");
            }
            progress.IsVisible = false;
        }

        void serviceClient_PhoneNumberAlreadyInDBCompleted(object sender, FindMeFriendServiceReference.PhoneNumberAlreadyInDBCompletedEventArgs e)
        {
            if (e.Result)
            {
                txtPhoneNumber.Background = new System.Windows.Media.SolidColorBrush(Colors.Red);
                validPhoneNumber = false;
                txbPhoneNumberInfo.Text = "*Phone number already in use";
            }
            else
            {
                txtPhoneNumber.Background = new System.Windows.Media.SolidColorBrush(Colors.Green);
                validPhoneNumber = true;
                txbPhoneNumberInfo.Text = string.Empty;
            }
        }

        void serviceClient_EmailAlreadyInDBCompleted(object sender, FindMeFriendServiceReference.EmailAlreadyInDBCompletedEventArgs e)
        {
            if (e.Result)
            {
                txtEmail.Background = new System.Windows.Media.SolidColorBrush(Colors.Red);
                validEmail = false;
                txbEmailInfo.Text = "*Email already in use";
            }
            else
            {
                txtEmail.Background = new System.Windows.Media.SolidColorBrush(Colors.Green);
                validEmail = true;
                txbEmailInfo.Text = string.Empty;
            }
        }

        void serviceClient_UsernameAlreadyInDBCompleted(object sender, FindMeFriendServiceReference.UsernameAlreadyInDBCompletedEventArgs e)
        {
            if (e.Result)
            {
                txtUsername.Background = new System.Windows.Media.SolidColorBrush(Colors.Red);
                validUsername = false;
                txbUsernameInfo.Foreground = new SolidColorBrush(Colors.Red);
                txbUsernameInfo.Text = txtUsername.Text + " is not available";
            }
            else
            {
                txtUsername.Background = new System.Windows.Media.SolidColorBrush(Colors.Green);
                validUsername = true;
                txbUsernameInfo.Foreground = new SolidColorBrush(Colors.Green);
                txbUsernameInfo.Text = txtUsername.Text + " is available";
            }
        }

        private void CancelBtn_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Login.xaml", UriKind.Relative));
        }

        private void SaveBtn_Click(object sender, RoutedEventArgs e)
        {
            progress.IsVisible = true;
            if (validUsername && validName && validPhoneNumber && validEmail && validPassword && validPassword2)
            {
                SHA1 sha1 = new SHA1Managed();
                byte[] passwordBytes = Encoding.Unicode.GetBytes(txtPassword.Password);
                byte[] hash = sha1.ComputeHash(passwordBytes);
                string hashedPassword = Encoding.Unicode.GetString(hash, 0, hash.Length);

                FindMeFriendServiceReference.CompositeType newUser = new FindMeFriendServiceReference.CompositeType()
                {
                    username = txtUsername.Text,
                    name = txtName.Text,
                    phonenumber = txtPhoneNumber.Text,
                    email = txtEmail.Text,
                    password = hashedPassword
                };

                serviceClient.AddNewUserAsync(newUser);
            }
            else
            {
                MessageBox.Show("Verify and fix your information first");
                progress.IsVisible = false;
            }
           
        }

        private void txtUsername_MouseLeave(object sender, MouseEventArgs e)
        {
            string result = validateUsername();

            txbUsernameInfo.Text = string.Empty;
            if (result == "valid")
            {
                try
                {
                    serviceClient.UsernameAlreadyInDBAsync(txtUsername.Text);
                }
                catch (Exception) { }
            }
            else
            {
                txtUsername.Background = new SolidColorBrush(Colors.Red);
                validUsername = false;
                txbUsernameInfo.Foreground = new SolidColorBrush(Colors.Red);
                txbUsernameInfo.Text = result;
            }
        }

        private void txtPhoneNumber_MouseLeave(object sender, MouseEventArgs e)
        {
            string result = validatePhoneNumber();

            txbPhoneNumberInfo.Text = string.Empty;
            if (result == "valid")
            {
                try
                {
                    serviceClient.PhoneNumberAlreadyInDBAsync(txtPhoneNumber.Text);
                }
                catch (Exception) { }
            }
            else
            {
                txtPhoneNumber.Background = new SolidColorBrush(Colors.Red);
                validPhoneNumber = false;
                txbPhoneNumberInfo.Text = result;
            }
        }

        private void txtEmail_MouseLeave(object sender, MouseEventArgs e)
        {
            string result = validateEmail();

            txbEmailInfo.Text = string.Empty;
            if (result == "valid")
            {
                try
                {
                    serviceClient.EmailAlreadyInDBAsync(txtEmail.Text);
                }
                catch (Exception) { }
            }
            else
            {
                txtEmail.Background = new SolidColorBrush(Colors.Red);
                validEmail = false;
                txbEmailInfo.Text = result;
            }
        }

        private void txtName_MouseLeave(object sender, MouseEventArgs e)
        {
            string result = validateName();

            txbNameInfo.Text = string.Empty;
            if (result == "valid")
            {
                txtName.Background = new SolidColorBrush(Colors.Green);
                validName = true;
                txbNameInfo.Text = string.Empty;
            }
            else
            {
                txtName.Background = new SolidColorBrush(Colors.Red);
                validName = false;
                txbNameInfo.Text = result;
            }
        }

        private void txtPassword_MouseLeave(object sender, MouseEventArgs e)
        {
            if (txtPassword.Password == string.Empty)
            {
                txtPassword.Background = new SolidColorBrush(Colors.Red);
                validPassword = false;
                txbPasswordInfo.Text = "*Password can't be empty";
            }
            else
            {
                txtPassword.Background = new SolidColorBrush(Colors.Green);
                validPassword = true;
                txbPasswordInfo.Text = string.Empty;
            }
        }

        private void txtPassword2_MouseLeave(object sender, MouseEventArgs e)
        {
            if (txtPassword2.Password == string.Empty)
            {
                txtPassword2.Background = new SolidColorBrush(Colors.Red);
                validPassword2 = false;
                txbPassword2Info.Text = "*Please verify your password";
            }
            else if (txtPassword.Password != txtPassword2.Password)
            {
                txtPassword2.Background = new SolidColorBrush(Colors.Red);
                validPassword2 = false;
                txbPassword2Info.Text = "*Passwords does not match";
            }
            else
            {
                txtPassword2.Background = new SolidColorBrush(Colors.Green);
                validPassword2 = true;
                txbPassword2Info.Text = string.Empty;
            }
        }

        private void txtName_TextChanged(object sender, TextChangedEventArgs e)
        {
            string name = txtName.Text;

            if (name.Contains("  "))
            {
                char[] tempChars = new char[name.Length - 1];
                for (int i = 0; i < name.Length - 1; i++)
                {
                    tempChars[i] = name[i];
                }

                txtName.Text = new string(tempChars);
                txtName.Select(txtName.Text.Length, 0);
            }
        }

        private string validateUsername()
        {
            string username = txtUsername.Text;

            if (username == string.Empty)
            {
                return "*Username can't be empty";
            }

            if (username[0] >= '0' && username[0] <= '9')
            {
                return "*Username can't start with numbers";
            }

            if (username.Length < 4)
            {
                return "*Username has to be at least 4 characters long";
            }

            foreach (char c in username)
            {
                if (c == ' ')
                {
                    return "*Username can't contain spaces";
                }
            }

            return "valid";
        }

        private string validateName()
        {
            string name = txtName.Text.Trim();

            if (name == string.Empty)
            {
                return "*Full Name can't be empty";
            }

            foreach (char c in name)
            {
                if (c != ' ' && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z'))
                {
                    return "*Full Name can only contain letters";
                }
            }

            string[] names = name.Split(new char[] { ' ' });

            if (names.Length < 2)
            {
                return "*Not a full name";
            }

            List<string> fixedNames = new List<string>();
            foreach (string n in names)
            {
                if (n.Length <= 0)
                {
                    return "*Not a full name";
                }

                string firstChar = n[0].ToString();
                firstChar = firstChar.ToUpper();

                char[] tempChars = new char[n.Length-1];
                int index = 0;
                for (int i = 1; i < n.Length; i++, index++)
                {
                    tempChars[index] = n[i];
                }

                string remChars = new string(tempChars);
                remChars = remChars.ToLower();

                fixedNames.Add(firstChar + remChars);
            }

            txtName.Text = string.Empty;
            while (fixedNames.Count > 0)
            {
                txtName.Text += fixedNames[0].ToString();
                fixedNames.RemoveAt(0);

                if (fixedNames.Count > 0)
                {
                    txtName.Text += ' ';
                }
            }
            return "valid";
        }

        private string validatePhoneNumber()
        {
            string phoneNumber = txtPhoneNumber.Text;

            if (phoneNumber == string.Empty)
            {
                return "*Phone Number can't be empty";
            }

            foreach (char c in phoneNumber)
            {
                if (c < '0' || c > '9')
                {
                    return "*Phone Number can only contain numbers";
                }
            }

            if (phoneNumber.Length < 10)
            {
                return "*Phone Number too short";
            }

            if (phoneNumber.Length == 11 && phoneNumber[0] != '1')
            {
                return "*Invalid Phone Number";
            }

            if (phoneNumber.Length > 11)
            {
                return "*Phone Number too long";
            }

            return "valid";
        }

        private string validateEmail()
        {
            string email = txtEmail.Text;

            if (email == string.Empty)
            {
                return "*Email can't be empty";
            }

            if (!email.Contains('@'))
            {
                return "*Invalid email address";
            }

            if (!email.Contains('.'))
            {
                return "*Invalid email address";
            }

            if (email.Contains("@."))
            {
                return "*Invalid email address";
            }

            if (email.Contains(".@"))
            {
                return "*Invalid email address";
            }

            if (email.Contains("@@"))
            {
                return "*Invalid email address";
            }

            if (email.Contains(".."))
            {
                return "*Invalid email address";
            }

            if (email.Contains(' '))
            {
                return "*Invalid email address";
            }

            return "valid";
        }
    }
}